package com.example.core.filter.flowctl;

import com.example.common.config.Rule;
import com.example.core.context.GatewayContext;
import com.example.core.filter.Filter;
import com.example.core.filter.FilterAspect;
import com.example.core.filter.flowctl.impl.FlowControlByPathRule;
import lombok.extern.slf4j.Slf4j;

import static com.example.common.constants.FilterConst.*;

/**
 * @Author Peng Yisheng
 * @Date 2024/12/6 17:18
 * @Description 流量控制过滤器：这里使用常见的令牌桶和漏桶算法
 */
@Slf4j
@FilterAspect(id = FLOW_CTL_FILTER_ID,
        name = FLOW_CTL_FILTER_NAME,
        order = FLOW_CTL_FILTER_ORDER)
public class FlowControlFilter implements Filter {

    @Override
    public void doFilter(GatewayContext ctx) throws Exception {
        Rule rule = ctx.getRule();
        if (rule == null) {
            return;
        }
        // 获取流控规则
        for (Rule.FlowControlConfig flowControlConfig : rule.getFlowCtlConfigs()) {
            IFlowControlRule flowControlRule = null;
            // path: /http/ping
            String path = ctx.getRequest().getPath();

            // 判断使用路径还是服务方式的流控
            if (flowControlConfig.getType().equalsIgnoreCase(FLOW_CTL_TYPE_PATH) && path.equals(flowControlConfig.getValue())) {
                flowControlRule = FlowControlByPathRule.getInstance(rule.getServiceId(), path);
            } else if (flowControlConfig.getType().equalsIgnoreCase(FLOW_CTL_TYPE_SERVICE)) {
                // TODO 后续实现基于服务的流控
            }
            if (flowControlRule != null) {
                //执行流量控制
                flowControlRule.doFlowControlFilter(flowControlConfig, rule.getServiceId());
            }
        }
    }
}
